/*
 *  Eschew - Even Simpler C-Heuristic Expat Wrapper - Example
 *  copyright (C) 2008-2010 Aperture Software
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *  ---------------------------------------------------------------------------
 * 	example.c: Demonstrates the parsing of an XML config file with eschew
 *  ---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 *	This needs to be defined in at least one source before including eschew.h
 *	The other sources just need to include eschew.h without this define
 */
#define INIT_XML_ACTUAL_INIT
#include "eschew.h"


#if defined(WIN32)
// Use the static expatMT lib
#pragma comment(lib, "libexpatMT.lib")
#endif

#define FLUSHER			{while(getchar() != 0x0A);}

/*
 *
 *	XML tables definitions (would normally go in a config.h or something)
 *
 *	If the following is the structure of the XML we would like to manipulate:
 *
 *	<?xml version="1.0" encoding="utf-8"?>
 *	<config>
 *	  <resolution>
 *		<scr_width>1280</scr_width>
 *		<scr_height>1024</scr_height>
 *		<fullscreen>enabled</fullscreen>
 *	  </resolution>
 *	  <!-- comments are preserved too -->
 *	  <keys player="1">
 *		<dir_left>&#x8C;</dir_left>
 *		<dir_right>&#x8E;</dir_right>
 *		<dir_up>&#x8D;</dir_up>
 *		<dir_down>&#x8F;</dir_down>
 *	  </keys>
 *	  <keys player="2">
 *		<dir_left>a</dir_left>
 *		<dir_right>d</dir_right>
 *		<dir_up>w</dir_up>
 *		<dir_down>s</dir_down>
 *	  </keys>
 *	  <messages>
 *		<msg1>ha ha! pwnd!</msg1>
 *		<msg2>%s has left the game</msg2>
 *	  </messages>
 *	</config>
 *
 *  Then we create the C XML tables with:
 */

// <config>: meta-node => xml_node type, and set as root
DEFINE_XML_NODES(config_nodes, resolution, keys, messages)
CREATE_XML_TABLE(config, config_nodes, xml_node)
SET_XML_ROOT(config)

// <resolution>: integer and boolean values => xml_int
DEFINE_XML_NODES(res_nodes, scr_width, scr_height, fullscreen)
CREATE_XML_TABLE(resolution, res_nodes, xml_int)

// <keys player="1"> & <keys player="2"> => 2 tables: keys_player_1 & keys_player_2
DEFINE_XML_NODES(keys_nodes, dir_left, dir_right, dir_up, dir_down)
CREATE_XML_TABLE(keys_player_1, keys_nodes, xml_unsigned_char)
CREATE_XML_TABLE(keys_player_2, keys_nodes, xml_unsigned_char)

// <messages>: set of string values
DEFINE_XML_NODES(msg_nodes, msg1, msg2)
CREATE_XML_TABLE(messages, msg_nodes, xml_string)

// The second part of a node table init occurs at runtime
void init_xml()
{
	INIT_XML_TABLE(config);
	INIT_XML_TABLE(resolution);
	INIT_XML_TABLE(keys_player_1);
	INIT_XML_TABLE(keys_player_2);
	INIT_XML_TABLE(messages);
}

// Optionally, you might want to set some values directly
void set_xml_defaults()
{
	SET_XML_NODE_DEFAULT(resolution, fullscreen, 0);
	SET_XML_NODE_COMMENT(resolution, fullscreen,
		"Toggle fullscreen on or off");
	SET_XML_NODE_DEFAULT(resolution, scr_width, 640);
	SET_XML_NODE_DEFAULT(resolution, scr_height, 480);
}

void display_xml(int request_input)
{
	char c;
	printf("\n******************************************************\n");
	printf("*                  CURRENT XML                       *\n");
	printf("******************************************************\n");
	write_xml("");
	if (request_input)
	{
		printf("\n");
		printf("Press Enter to continue\n");
		fflush(stdin);
		do
			c = (char) getchar();
		while (c!=0x0A);
	}
}

int main (int argc, char *argv[])
{
	const char confname[] = "config.xml";

	// Complete the initialization
	init_xml();

	/*
	 * At this stage, all our C XML tables are accessible
	 * under the name: xml_<name_used_in_create>
	 */

	printf("\nXML tables have been created.\n"
		"Now setting some default table values and XML comments...\n");
	set_xml_defaults();

	display_xml(1);

	printf("Now reading from file '%s' and populating table values...\n", confname);
	if (!read_xml(confname))
	{
		fprintf(stderr, "Could not process file - Is it available in the current directory?\n");
		goto out;
	}
	display_xml(1);

	printf("Now processing code line: xml_keys_player_1.value[dir_left]  = '4';\n");
	xml_keys_player_1.value[dir_left]  = '4';
	printf("Now processing code line: xml_keys_player_1.value[dir_right] = '6';\n");
	xml_keys_player_1.value[dir_right] = '6';
	printf("Now processing code line: xml_keys_player_1.value[dir_up]    = '8';\n");
	xml_keys_player_1.value[dir_up]    = '8';
	printf("Now processing code line: xml_keys_player_1.value[dir_down]  = '2';\n");
	xml_keys_player_1.value[dir_down]  = '2';

	display_xml(0);

out:
	// Make sure you clean up the data when done
	free_xml();

	return 0;
}
